package com.youlu.campus.service.platform.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.PointPlatformTaskConfigQueryVO;
import com.youlu.campus.entity.PointPlatformTaskConfigVO;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.entity.platform.PlatformTaskInfo;
import com.youlu.campus.service.platform.PointPlatformTaskConfigService;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PointPlatformTaskConfigServiceImpl implements PointPlatformTaskConfigService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    protected MapperFacade mapperFacade;

    @Override
    public PlatformTaskInfo findOne(String id) {
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        return mongoTemplate.findOne(query, PlatformTaskInfo.class);
    }

    @Override
    public PlatformTaskInfo findTmplByAppId(PointPlatformTaskConfigQueryVO req) {
        TaskBizType taskBizType = req.getTaskBizType();
        if(Objects.isNull(taskBizType)){
         taskBizType  =TaskBizType.SUBSCRIPTION;
        }
        Query query = new Query().addCriteria(Criteria.where("appId").is(req.getAppId()).and("platform").is(req.getPlatform()).and("taskBizType").is(taskBizType).and("deleted").is(Boolean.FALSE));
        return mongoTemplate.findOne(query, PlatformTaskInfo.class);
    }

    @Override
    public Page<PlatformTaskInfo> find(@NotNull PointPlatformTaskConfigQueryVO req) {
        Query query = new Query().addCriteria(Criteria.where("appId").is(req.getAppId()).and("platform").is(req.getPlatform()).and("deleted").is(Boolean.FALSE));
//        query.with(new Sort(Sort.Direction.DESC, "priority"));
        Sort sort=Sort.by(Sort.Direction.DESC, "priority");
        query.with(sort);
        Long count = mongoTemplate.count(query, PlatformTaskInfo.class);

        if (Objects.isNull(req.getPageSize())) {
            req.setPageSize(10);
        }
        if (Objects.isNull(req.getPage())) {
            req.setPage(1);
        }
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
        List<PlatformTaskInfo> platformTaskInfos = mongoTemplate.find(query.with(pageRequest), PlatformTaskInfo.class);
        return PageableExecutionUtils.getPage(platformTaskInfos, pageRequest, () -> count);
    }

    @Override
    public Page<PointPlatformTaskConfigVO> list(PointPlatformTaskConfigQueryVO req) {
        Query query = new Query().addCriteria(Criteria.where("appId").is(req.getAppId()).and("platform").is(req.getPlatform()).and("deleted").is(Boolean.FALSE).and("status").is(1));
//        query.with(new Sort(Sort.Direction.DESC, "priority"));
        Sort sort=Sort.by(Sort.Direction.DESC, "priority");
        query.with(sort);
        Long count = mongoTemplate.count(query, PlatformTaskInfo.class);

        if (Objects.isNull(req.getPageSize())) {
            req.setPageSize(10);
        }
        if (Objects.isNull(req.getPage())) {
            req.setPage(1);
        }
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
        List<PlatformTaskInfo> platformTaskInfos = mongoTemplate.find(query.with(pageRequest), PlatformTaskInfo.class);
        List<PointPlatformTaskConfigVO> list = platformTaskInfos.stream().map(platformTaskInfo -> {
            PointPlatformTaskConfigVO pointPlatformTaskConfigVO = mapperFacade.map(platformTaskInfo,PointPlatformTaskConfigVO.class);
            return pointPlatformTaskConfigVO;
        }).collect(Collectors.toList());
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    @Override
    public boolean delete(@NotNull String id) {
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        update.set("deleted", true);
        update.set("updatedTime", new Date());
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, PlatformTaskInfo.class);
        return updateResult.getModifiedCount() > 0 ? true : false;
    }

    @Override
    public boolean update(@NotNull PlatformTaskInfo req) {
        log.info(":>>> 开始修改积分平台任务配置:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getId())) {
            return false;
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(req.getId()));
        Update update = new Update();
        if (StringUtils.isNotBlank(req.getLogo())) {
            update.set("logo", req.getLogo());
        }
        if (StringUtils.isNotBlank(req.getTitle())) {
            update.set("title", req.getTitle());
        }
        if (StringUtils.isNotBlank(req.getSubTitle())) {
            update.set("subTitle", req.getSubTitle());
        }
        if (StringUtils.isNotBlank(req.getButtonName())) {
            update.set("buttonName", req.getButtonName());
        }
        if (Objects.nonNull(req.getTaskBizType())) {
            update.set("taskBizType", req.getTaskBizType());
        }
        if (Objects.nonNull(req.getQuantity())) {
            update.set("quantity", req.getQuantity());
        }
        if (Objects.nonNull(req.getTaskBizType())) {
            update.set("threshold", req.getThreshold());
        }
        if (req.getStatus()!=null) {
            update.set("status", req.getStatus());
        }
        if (req.getPriority()!=null) {
            update.set("priority", req.getPriority());
        }
        if(CollectionUtils.isEmpty(req.getTaskExtra())){
            update.set("taskExtra", new ArrayList());
        }else {
            update.set("taskExtra", req.getTaskExtra());
        }
        if(Objects.nonNull(req.getOpenSub())){
            update.set("openSub", req.getOpenSub());
        }
        update.set("updatedTime", new Date());
        if(!this.checkUnique(req)){
            throw new BusinessException("任务不唯一");
        }
        return mongoTemplate.updateFirst(query, update, PlatformTaskInfo.class).getModifiedCount() > 0 ? true : false;
    }

    @Override
    public boolean create(@NotNull PlatformTaskInfo req) {
        req.setId(null);
        req.setCreatedTime(new Date());
        if(!this.checkUnique(req)){
            throw new BusinessException("任务不唯一");
        }
        req = mongoTemplate.insert(req);
        if (StringUtils.isNotBlank(req.getId())) {
            return true;
        }
        return false;
    }

    protected boolean checkUnique(PlatformTaskInfo req){
        Query query = new Query().addCriteria(Criteria.where("appId").is(req.getAppId()).and("platform").is(req.getPlatform()).and("taskBizType").is(req.getTaskBizType()).and("deleted").is(Boolean.FALSE));
        if(req.getId()!=null){
            query.addCriteria(Criteria.where("id").ne(req.getId()));
        }
        Long count = mongoTemplate.count(query, PlatformTaskInfo.class);
        return count<=0;
    }


}
